package co.fitstart.entity.credit.order;

import java.beans.Transient;
import java.util.Date;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import org.springframework.format.annotation.DateTimeFormat;
import com.alibaba.fastjson.annotation.JSONField;
import com.demo2do.core.format.DecimalFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import co.fitstart.entity.credit.product.CreditProduct;
import co.fitstart.entity.credit.product.CreditProductType;
import co.fitstart.entity.user.Student;
import co.fitstart.entity.user.User;
import co.fitstart.entity.user.UserAddress;

/**
 * 
 * @author mohanlan
 *
 */
@Entity
@Table(name = "credit_order")
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class CreditOrder {

	@Id
	@GeneratedValue
	private Long id;

	private String code;

	private CreditProductType type;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	private CreditProduct product;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	private User user;

	@ManyToOne(fetch = FetchType.LAZY, optional = true)
	private Student student;

	/** 原积分（总计） */
    @DecimalFormat
    private int originalPrice;
    
    /** 订单积分（总计） */
    @DecimalFormat
    private int price;
    
    /** 订单积分单价 */
    @DecimalFormat
    private int unitPrice;
    
    /** 份数 */
    private int amount;
    
    /** 创建时间/下单时间 */
    private Date createTime;
    
    /** 兑换时间 */
    private Date exchangeTime;
    
    /** 备注 */
    private String remarks;
    
    /** 实物商品配送地址 */
    @ManyToOne(fetch = FetchType.LAZY)
    private UserAddress userAddress;
    
    /** 实物商品配送地址 */
    private String contactName;
    
    /** 实物商品配送地址 */
    private String contactPhone;
    
    /** 实物商品配送地址 */
    private String province;
    
    /** 实物商品配送地址 */
    private String city;
    
    /** 实物商品配送地址 */
    private String region;
    
    /** 实物商品配送地址 */
    private String address;
    
    /** 实物商品配送地址 */
    private String zipCode;
    
    /** 虚拟积分商品码 */
    private String couponCode;
    
    /** 虚拟优惠券Id */
    private Long couponId;
    
    /** 券有效期 - 开始时间 */
    @Type(type = "date")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JSONField(format = "yyyy-MM-dd")
    private Date effectiveStartDate;

    /** 券有效期 - 截止时间/过期时间 */
    @Type(type = "date")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JSONField(format = "yyyy-MM-dd")
    private Date effectiveEndDate;
    
    /** 运单号*/
    private String waybillCode;
    
    /** 送货公司*/
    private String shippingOffice;
    
    @Enumerated(value = EnumType.ORDINAL)
    private CreditOrderStatus status;
    
    /** 订单属性 */
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @MapKey(name = "name")
    private Map<String, CreditOrderAttr> attrs;
    
    /** 是否删除 */
    @Column(name = "is_disabled")
    private boolean disabled;
    
    public CreditOrder() {
	}

    /**
	 * @param creditProduct
	 * @param userAddress
	 * @param amount
	 * @param student
	 * @return
	 */
	public CreditOrder initProduct(String creditOrderNo, CreditProduct creditProduct, UserAddress userAddress,
			Integer amount, Student student) {

		this.setCode(creditOrderNo);

		this.setType(creditProduct.getType());

		this.setProduct(creditProduct);

		this.setUser(userAddress.getUser());

		this.setStudent(student);

		if (student != null) {

			this.setStudent(student);
		}
		this.setOriginalPrice(creditProduct.getPrice().intValue() * amount);

		this.setPrice(creditProduct.getCurrentPrice().intValue() * amount);

		this.setUnitPrice(creditProduct.getCurrentPrice().intValue());

		this.setAmount(amount);

		this.setCreateTime(new Date());

		this.setExchangeTime(new Date());

		this.setUserAddress(userAddress);

		this.setContactName(userAddress.getContactName());

		this.setContactPhone(userAddress.getContactPhone());

		this.setProvince(userAddress.getProvince());

		this.setCity(userAddress.getCity());

		this.setRegion(userAddress.getRegion());

		this.setAddress(userAddress.getAddress());

		this.setZipCode(userAddress.getZipCode());

		this.setStatus(CreditOrderStatus.CREATED);
		
		return this;
	}

	/**
	 * @param creditOrderNo
	 * @param creditProduct
	 * @param amount
	 * @param student
	 * @param coupon 
	 * @param user
	 */
	public CreditOrder initCoupon(String creditOrderNo, CreditProduct creditProduct, Integer amount, Student student, 
								  String couponCode, User user) {

		this.setCode(creditOrderNo);

		this.setType(creditProduct.getType());

		this.setProduct(creditProduct);

		this.setUser(user);

		this.setStudent(student);

		if (student != null) {

			this.setStudent(student);
		}
		this.setOriginalPrice(creditProduct.getPrice().intValue() * amount);

		this.setPrice(creditProduct.getCurrentPrice().intValue() * amount);

		this.setUnitPrice(creditProduct.getCurrentPrice().intValue());

		this.setAmount(amount);

		this.setCreateTime(new Date());

		this.setExchangeTime(new Date());
		
		this.setStatus(CreditOrderStatus.CREATED);
		
		this.setCouponCode(couponCode);
		
		return this;
	}
	
	/**
	 * 
	 * @return
	 */
	@Transient
	public String[] getCouponCodes() {
		if(this.couponCode != null) {
			return couponCode.split(",");
		} else {
			return null;
		}
	}
	
    /**
     * 
     * @return
     */
    public CreditOrder mark() {
    	this.status = CreditOrderStatus.SHIPPED;
    	this.exchangeTime = new Date();
    	return this;
    }
	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @return the type
	 */
	public CreditProductType getType() {
		return type;
	}

	/**
	 * @return the product
	 */
	public CreditProduct getProduct() {
		return product;
	}

	/**
	 * @return the user
	 */
	public User getUser() {
		return user;
	}

	/**
	 * @return the student
	 */
	public Student getStudent() {
		return student;
	}

	/**
	 * @return the originalPrice
	 */
	public int getOriginalPrice() {
		return originalPrice;
	}

	/**
	 * @return the price
	 */
	public int getPrice() {
		return price;
	}

	/**
	 * @return the amount
	 */
	public int getAmount() {
		return amount;
	}

	/**
	 * @return the createTime
	 */
	public Date getCreateTime() {
		return createTime;
	}

	/**
	 * @return the exchangeTime
	 */
	public Date getExchangeTime() {
		return exchangeTime;
	}

	/**
	 * @return the remarks
	 */
	public String getRemarks() {
		return remarks;
	}

	/**
	 * @return the userAddress
	 */
	public UserAddress getUserAddress() {
		return userAddress;
	}

	/**
	 * @return the contactName
	 */
	public String getContactName() {
		return contactName;
	}

	/**
	 * @return the contactPhone
	 */
	public String getContactPhone() {
		return contactPhone;
	}

	/**
	 * @return the province
	 */
	public String getProvince() {
		return province;
	}

	/**
	 * @return the city
	 */
	public String getCity() {
		return city;
	}

	/**
	 * @return the region
	 */
	public String getRegion() {
		return region;
	}

	/**
	 * @return the address
	 */
	public String getAddress() {
		return address;
	}

	/**
	 * @return the zipCode
	 */
	public String getZipCode() {
		return zipCode;
	}

	/**
	 * @return the couponCode
	 */
	public String getCouponCode() {
		return couponCode;
	}

	/**
	 * @return the couponId
	 */
	public Long getCouponId() {
		return couponId;
	}

	/**
	 * @return the status
	 */
	public CreditOrderStatus getStatus() {
		return status;
	}

	/**
	 * @return the attrs
	 */
	public Map<String, CreditOrderAttr> getAttrs() {
		return attrs;
	}

	/**
	 * @return the disabled
	 */
	public boolean isDisabled() {
		return disabled;
	}

	/**
	 * @return the unitPrice
	 */
	public int getUnitPrice() {
		return unitPrice;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @param code
	 *            the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @param type
	 *            the type to set
	 */
	public void setType(CreditProductType type) {
		this.type = type;
	}

	/**
	 * @param product
	 *            the product to set
	 */
	public void setProduct(CreditProduct product) {
		this.product = product;
	}

	/**
	 * @param user
	 *            the user to set
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * @param student
	 *            the student to set
	 */
	public void setStudent(Student student) {
		this.student = student;
	}

	/**
	 * @param originalPrice
	 *            the originalPrice to set
	 */
	public void setOriginalPrice(int originalPrice) {
		this.originalPrice = originalPrice;
	}

	/**
	 * @param price
	 *            the price to set
	 */
	public void setPrice(int price) {
		this.price = price;
	}

	/**
	 * @param amount
	 *            the amount to set
	 */
	public void setAmount(int amount) {
		this.amount = amount;
	}

	/**
	 * @param createTime
	 *            the createTime to set
	 */
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	/**
	 * @param exchangeTime
	 *            the exchangeTime to set
	 */
	public void setExchangeTime(Date exchangeTime) {
		this.exchangeTime = exchangeTime;
	}

	/**
	 * @param remarks
	 *            the remarks to set
	 */
	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	/**
	 * @param userAddress
	 *            the userAddress to set
	 */
	public void setUserAddress(UserAddress userAddress) {
		this.userAddress = userAddress;
	}

	/**
	 * @param contactName
	 *            the contactName to set
	 */
	public void setContactName(String contactName) {
		this.contactName = contactName;
	}

	/**
	 * @param contactPhone
	 *            the contactPhone to set
	 */
	public void setContactPhone(String contactPhone) {
		this.contactPhone = contactPhone;
	}

	/**
	 * @param province
	 *            the province to set
	 */
	public void setProvince(String province) {
		this.province = province;
	}

	/**
	 * @param city
	 *            the city to set
	 */
	public void setCity(String city) {
		this.city = city;
	}

	/**
	 * @param region
	 *            the region to set
	 */
	public void setRegion(String region) {
		this.region = region;
	}

	/**
	 * @param address
	 *            the address to set
	 */
	public void setAddress(String address) {
		this.address = address;
	}

	/**
	 * @param zipCode
	 *            the zipCode to set
	 */
	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	/**
	 * @param couponCode
	 *            the couponCode to set
	 */
	public void setCouponCode(String couponCode) {
		this.couponCode = couponCode;
	}

	/**
	 * @param couponId
	 *            the couponId to set
	 */
	public void setCouponId(Long couponId) {
		this.couponId = couponId;
	}

	/**
	 * @param status
	 *            the status to set
	 */
	public void setStatus(CreditOrderStatus status) {
		this.status = status;
	}

	/**
	 * @param attrs
	 *            the attrs to set
	 */
	public void setAttrs(Map<String, CreditOrderAttr> attrs) {
		this.attrs = attrs;
	}

	/**
	 * @param disabled
	 *            the disabled to set
	 */
	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}

	/**
	 * @param unitPrice
	 *            the unitPrice to set
	 */
	public void setUnitPrice(int unitPrice) {
		this.unitPrice = unitPrice;
	}
	
	/**
	 * 
	 * @return
	 */
	public Date getEffectiveStartDate() {
		return effectiveStartDate;
	}

	/**
	 * 
	 * @param effectiveStartDate
	 */
	public void setEffectiveStartDate(Date effectiveStartDate) {
		this.effectiveStartDate = effectiveStartDate;
	}

	/**
	 * 
	 * @return
	 */
	public Date getEffectiveEndDate() {
		return effectiveEndDate;
	}

	/**
	 * 
	 * @param effectiveEndDate
	 */
	public void setEffectiveEndDate(Date effectiveEndDate) {
		this.effectiveEndDate = effectiveEndDate;
	}

	/**
	 * 
	 * @return
	 */
	public String getWaybillCode() {
		return waybillCode;
	}

	/**
	 * 
	 * @param waybillCode
	 */
	public void setWaybillCode(String waybillCode) {
		this.waybillCode = waybillCode;
	}

	/**
	 * 
	 * @return
	 */
	public String getShippingOffice() {
		return shippingOffice;
	}

	/**
	 * 
	 * @param shippingOffice
	 */
	public void setShippingOffice(String shippingOffice) {
		this.shippingOffice = shippingOffice;
	}


	
}
